package com.fadis.protocol;

import com.fadis.FadisException;
import com.fadis.cmd.FadisActionFrame;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Resp {

    public static void print(BaseRespProtocol p){
        System.out.println(parseToStr(p));
    }

    private static String parseToStr(BaseRespProtocol p) {
        String s = "";
        if(p == null){
            s = "(nil)";
        }else if(p instanceof SimpleString){
            s = "\"" + ((SimpleString) p).getStr() + "\"";
        }else if(p instanceof BulkString){
            s = "\"" + ((BulkString) p).getStr() + "\"";
        }else if(p instanceof LongNumber){
            s = "(integer)" + ((LongNumber) p).getNumber();
        }else if(p instanceof ErrorString){
            s = "(error)" + ((ErrorString) p).getStr();
        }else if(p instanceof RespArray){
            RespArray a = (RespArray) p;
            if(a.isNull()) {
                s = "(nil)";
            }else if(a.getCount() == 0){
                s = "空数组或集合";
            }else{
                for (int i = 0; i < a.getCount(); i++) {
                    s += "(" + i + ")" + parseToStr(a.get(i)) + "\r\n";
                }
            }
        }else{
            s = "unknown protocol";
        }
        return s;
    }

    private static void tryToRaiseError(BaseRespProtocol p){
        if(p instanceof ErrorString){
            throw new FadisException(-1, ((ErrorString) p).getStr());
        }
    }

    public static String getStringOK(BaseRespProtocol p){
        tryToRaiseError(p);
        if(p == null){
            return null;
        }else if(p instanceof SimpleString){
            return ((SimpleString) p).getStr();
        }else{
            throw new FadisException(4006, "非期望的返回类型 -- " + p.getClass().getSimpleName());
        }
    }

    public static String getString(BaseRespProtocol p){
        tryToRaiseError(p);
        if(p == null){
            return null;
        }else if(p instanceof SimpleString){
            return ((SimpleString) p).getStr();
        }else if(p instanceof BulkString){
            return ((BulkString) p).getStr();
        }else if(p instanceof LongNumber){
            return ((LongNumber) p).getNumber() + "";
        }else if(p instanceof RespArray){
            throw new FadisException(4006, "非期望的返回类型 -- " + p.getClass().getSimpleName());
        }else{
            throw new FadisException(4006, "非期望的返回类型 -- " + p.getClass().getSimpleName());
        }
    }

    public static Long getLong(BaseRespProtocol p){
        tryToRaiseError(p);
        try {
            if(p == null){
                return null;
            }else if(p instanceof SimpleString){
                return Long.parseLong(((SimpleString) p).getStr());
            }else if(p instanceof BulkString){
                return Long.parseLong(((BulkString) p).getStr());
            }else if(p instanceof LongNumber){
                return ((LongNumber) p).getNumber();
            }else if(p instanceof RespArray){
                throw new FadisException(4006, "非期望的返回类型 -- " + p.getClass().getSimpleName());
            }else{
                throw new FadisException(4006, "非期望的返回类型 -- " + p.getClass().getSimpleName());
            }
        }catch (Exception e){
            throw new FadisException(4006, "非long类型");
        }

    }

    public static Integer getInteger(BaseRespProtocol p){
        tryToRaiseError(p);
        try {
            if(p == null){
                return null;
            }else if(p instanceof SimpleString){
                return Integer.parseInt(((SimpleString) p).getStr());
            }else if(p instanceof BulkString){
                return Integer.parseInt(((BulkString) p).getStr());
            }else if(p instanceof LongNumber){
                return (int)((LongNumber) p).getNumber();
            }else if(p instanceof RespArray){
                throw new FadisException(4006, "非期望的返回类型 -- " + p.getClass().getSimpleName());
            }else{
                throw new FadisException(4006, "非期望的返回类型 -- " + p.getClass().getSimpleName());
            }
        }catch (Exception e){
            throw new FadisException(4006, "非int类型");
        }

    }

    public static Double getDouble(BaseRespProtocol p){
        tryToRaiseError(p);
        try {
            if(p == null){
                return null;
            }else if(p instanceof SimpleString){
                return Double.parseDouble(((SimpleString) p).getStr());
            }else if(p instanceof BulkString){
                return Double.parseDouble(((BulkString) p).getStr());
            }else if(p instanceof LongNumber){
                return (double)((LongNumber) p).getNumber();
            }else if(p instanceof RespArray){
                throw new FadisException(4006, "非期望的返回类型 -- " + p.getClass().getSimpleName());
            }else{
                throw new FadisException(4006, "非期望的返回类型 -- " + p.getClass().getSimpleName());
            }
        }catch (Exception e){
            throw new FadisException(4006, "非double类型");
        }
    }



    public static List<String> getStringList(BaseRespProtocol resp){
        tryToRaiseError(resp);
        if(resp == null){
            return null;
        }else if(resp instanceof RespArray){
            RespArray a = (RespArray) resp;
            if(a.isNull()) return null;
            List<String> list = new ArrayList<>();
            for (int i = 0; i < a.getCount(); i++) {
                BaseRespProtocol cmd = a.get(i);
                list.add(getString(cmd));
            }
            return list;
        }else{
            throw new FadisException(4006, "非期望的返回类型 -- " + resp.getClass().getSimpleName());
        }
    }

    public static Set<String> getStringSet(BaseRespProtocol resp){
        tryToRaiseError(resp);
        if(resp == null){
            return null;
        }else if(resp instanceof RespArray){
            RespArray a = (RespArray) resp;
            if(a.isNull()) return null;
            Set<String> list = new HashSet<>();
            for (int i = 0; i < a.getCount(); i++) {
                BaseRespProtocol cmd = a.get(i);
                list.add(getString(cmd));
            }
            return list;
        }else{
            throw new FadisException(4006, "非期望的返回类型 -- " + resp.getClass().getSimpleName());
        }
    }

    public static List<Long> getLongList(BaseRespProtocol resp){
        tryToRaiseError(resp);
        if(resp == null){
            return null;
        }else if(resp instanceof RespArray){
            RespArray a = (RespArray) resp;
            if(a.isNull()) return null;
            List<Long> list = new ArrayList<>();
            for (int i = 0; i < a.getCount(); i++) {
                BaseRespProtocol cmd = a.get(i);
                list.add(getLong(cmd));
            }
            return list;
        }else{
            throw new FadisException(4006, "非期望的返回类型 -- " + resp.getClass().getSimpleName());
        }
    }

    public static List<Integer> getIntegerList(BaseRespProtocol resp){
        tryToRaiseError(resp);
        if(resp == null){
            return null;
        }else if(resp instanceof RespArray){
            RespArray a = (RespArray) resp;
            if(a.isNull()) return null;
            List<Integer> list = new ArrayList<>();
            for (int i = 0; i < a.getCount(); i++) {
                BaseRespProtocol cmd = a.get(i);
                list.add(getInteger(cmd));
            }
            return list;
        }else{
            throw new FadisException(4006, "非期望的返回类型 -- " + resp.getClass().getSimpleName());
        }
    }

    public static List<Double> getDoubleList(BaseRespProtocol resp){
        tryToRaiseError(resp);
        if(resp == null){
            return null;
        }else if(resp instanceof RespArray){
            RespArray a = (RespArray) resp;
            if(a.isNull()) return null;
            List<Double> list = new ArrayList<>();
            for (int i = 0; i < a.getCount(); i++) {
                BaseRespProtocol cmd = a.get(i);
                list.add(getDouble(cmd));
            }
            return list;
        }else{
            throw new FadisException(4006, "非期望的返回类型 -- " + resp.getClass().getSimpleName());
        }
    }

    public static FadisActionFrame parseToFrame(String cmd){
        FadisActionFrame f = new FadisActionFrame();
        RespArray a = CmdDecoder.getDefault().decodeArray(cmd);
        for (int i = 0; i < a.getCount(); i++) {
            f.appendArg(getString(a.get(i)));
        }
        return f;
    }

    public static String parseToCmd(FadisActionFrame f){
        return RespArray.encodeList(f.getArgs());
    }


}
